package com.example.saiaadmin.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.saiaadmin.common.GetCunrrentUser;
import com.example.saiaadmin.common.JwtUtil;
import com.example.saiaadmin.common.RedisUtils;
import com.example.saiaadmin.dto.DTOEbSystemUser;
import com.example.saiaadmin.entry.*;
import com.example.saiaadmin.po.CusterUserDetails;
import com.example.saiaadmin.service.*;
import com.example.saiaadmin.utils.PageBean;
import com.example.saiaadmin.utils.ResultData;
import com.example.saiaadmin.vo.VOEbSystemUser;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 用户信息表Controller
 *
 * @author Vagrant
 * @since 2025/01/13
 */
@RestController
@RequestMapping("/eb-system-user")
public class EbSystemUserController {


    @Autowired
    private EbSystemUserService service;
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Qualifier("authenticationManager")
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private EbSystemMenuService ebSystemMenuService;

    @Autowired
    private EbSystemUploadfileService uploadfileService;
    @Autowired
    private EbSystemLoginLogService loginLogService;
    @Autowired
    private EbSystemOperLogService operLogService;

    /**
     * 获取验证码
     *
     * @return
     */
    @GetMapping("/getCode")
    public ResultData<Map> getCode() {
        // 设置验证码图片长、宽、验证码字符数、干扰线宽度
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 30, 4, 10);
        // 获取验证码
        String code = lineCaptcha.getCode();
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // 存入 redis
        redisUtils.set(uuid, code, 180, TimeUnit.SECONDS);
        // 转为 Base64 字符串
        String imageBase64Data = lineCaptcha.getImageBase64Data();
        Map<String, Object> map = new HashMap<>();
        map.put("uuid", uuid);
        map.put("verifyCode", imageBase64Data);
        return ResultData.success("请求成功", map);
    }

    /**
     * 校验验证码
     *
     * @param uuid
     * @param verifyCode
     * @return
     */
    @GetMapping("/checkCode")
    public ResultData<String> checkCode(String uuid, String verifyCode) {
        if (!StringUtils.hasLength(uuid) || !StringUtils.hasLength(verifyCode)) {
            return ResultData.error("请输入参数");
        }
        String reverifyCode = redisUtils.get(uuid);
        if (null == reverifyCode) {
            return ResultData.error("验证码已过期");
        }
        if (verifyCode.equals(reverifyCode)) {
            return ResultData.success("验证成功");
        } else {
            return ResultData.error("验证失败");
        }
    }

    /**
     * 注册账号
     *
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/register")
    public ResultData<String> register(String username, String password) {
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return ResultData.error("请输入参数");
        }
        LambdaQueryWrapper<EbSystemUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EbSystemUser::getUsername, username);
        int count = (int) service.count(queryWrapper);
        if (count > 0) {
            return ResultData.error("该账号已注册");
        }
        password = passwordEncoder.encode(password);
        EbSystemUser user = new EbSystemUser();
        user.setUsername(username);
        user.setPassword(password);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        service.save(user);
        return ResultData.success("注册成功");
    }

    /**
     * 登录接口 传参以及类型都要符合 以json形式
     *
     * @param ebSystemUser
     * @return
     */
    @PostMapping("/login")
    // public ResultData<String> login(@RequestBody EbSystemUser ebSystemUser) {
    public ResultData<String> login(@RequestBody VOEbSystemUser ebSystemUser) {
        try {
            if (!StringUtils.hasLength(ebSystemUser.getUsername()) || !StringUtils.hasLength(ebSystemUser.getPassword())) {
                return ResultData.error("请输入账号！");
            }
            String uuid = ebSystemUser.getUuid();
            String verifyCode = ebSystemUser.getVerifyCode();
            if (!StringUtils.hasLength(uuid) || !StringUtils.hasLength(verifyCode)) {
                return ResultData.error("请输入参数");
            }
            String reverifyCode = redisUtils.get(uuid);
            if (null == reverifyCode) {
                return ResultData.error("验证码已过期");
            }
            if (!verifyCode.toLowerCase().equals(reverifyCode.toLowerCase())) {
                return ResultData.error("验证码错误");
            }

                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(ebSystemUser.getUsername(), ebSystemUser.getPassword());
                Authentication authentication = authenticationManager.authenticate(auth);
                SecurityContextHolder.getContext().setAuthentication(authentication);
                CusterUserDetails userDetails = (CusterUserDetails) authentication.getPrincipal();
                //数据库密码
                String passwords = userDetails.getUser().getPassword();
                //传进来的密码
                // String encryptedPassword = passwordEncoder.encode(ebSystemUser.getPassword());
                if (passwordEncoder.matches(ebSystemUser.getPassword(), passwords)) {
                    //用户身份验证成功，生成并返回jwt令牌
                    Map<String, Object> claims = new HashMap<>();
                    claims.put("username", userDetails.getUser().getUsername());
                    claims.put("id", userDetails.getUser().getId());
                    String jwtToken = JwtUtil.createJWT(claims);
                    redisUtils.set(userDetails.getUser().getUsername() + "Authorization", jwtToken, 7200L, TimeUnit.SECONDS);
                    return ResultData.success("登录成功", jwtToken);
                } else {
                    return ResultData.error("用户名或密码错误！");
                }

        } catch (Exception ex) {
            //用户身份验证失败，返回登陆失败提示
            return ResultData.error("用户名或密码错误！");
        }
    }

    /**
     * 获取当前用户
     * @return
     */
    @GetMapping("/getUser")
    public ResultData<Map> getUser() {
        GetCunrrentUser getCunrrentUser = new GetCunrrentUser();
        EbSystemUser systemUser=getCunrrentUser.getUser();
        DTOEbSystemUser dtoEbSystemUser  = service.getUserEntry(systemUser.getUsername());
        EbSystemMenu ebSystemMenu = new EbSystemMenu();
        List<EbSystemMenu> list = ebSystemMenuService.listMenu(ebSystemMenu);
        Map<String,Object> map =  new HashMap<>();
        map.put("user",dtoEbSystemUser);
        map.put("codes","*");
        map.put("roles","superAdmin");
        map.put("routers",list);
        return ResultData.success("获取成功", map);
    }

    /**
     * 获取当前用户列表
     * @return
     */
    @GetMapping("/getUserList")
    public ResultData<PageBean<EbSystemUser>> getUserList(Integer pageNum,Integer pageSize) {
        if(null == pageNum){
            pageNum =1;
        }
        if(null == pageSize){
            pageSize =1;
        }
        Page<EbSystemUser> pageInfo = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<EbSystemUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(EbSystemUser::getUpdateTime);
         service.page(pageInfo,queryWrapper);
        PageBean<EbSystemUser> pageBean = new PageBean<>();
        pageBean.setTotal(pageInfo.getTotal());
        pageBean.setData(pageInfo.getRecords());
        pageBean.setPer_page((int) pageInfo.getSize());
        pageBean.setLast_page((int) pageInfo.getPages());
        return ResultData.success("获取成功", pageBean);
    }

    /**
     * 通过id 列表获取用户基础信息
     * @return
     */
    @GetMapping("/getUserInfoByIds")
    public ResultData<EbSystemUser> getUserInfoByIds(String id) {

        LambdaQueryWrapper<EbSystemUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EbSystemUser::getId,id);
        queryWrapper.orderByDesc(EbSystemUser::getUpdateTime);
        EbSystemUser ebSystemUser = service.getOne(queryWrapper);
        return ResultData.success("获取成功", ebSystemUser);
    }

    /**
     * 获取当前用户列表
     * @return
     */
    @GetMapping("/index")
    public ResultData<PageBean<EbSystemUser>> index(Integer page,Integer limit,String username,String phone,String email,Integer status,Integer dept_id) {
        if(null == page){
            page =1;
        }
        if(null == limit){
            limit =1;
        }
        Page<EbSystemUser> pageInfo = new Page<>(page,limit);
        LambdaQueryWrapper<EbSystemUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(null != username,EbSystemUser::getUsername,username);
        queryWrapper.eq(null !=phone,EbSystemUser::getPhone,phone);
        queryWrapper.eq(null != email,EbSystemUser::getEmail,email);
        queryWrapper.eq(null != status,EbSystemUser::getStatus,status);
        queryWrapper.eq(null != dept_id,EbSystemUser::getDeptId,dept_id);
        queryWrapper.orderByDesc(EbSystemUser::getUpdateTime);
        service.page(pageInfo,queryWrapper);
        PageBean<EbSystemUser> pageBean = new PageBean<>();
        pageBean.setTotal(pageInfo.getTotal());
        pageBean.setData(pageInfo.getRecords());
        pageBean.setPer_page((int) pageInfo.getSize());
        pageBean.setLast_page((int) pageInfo.getPages());
        return ResultData.success("获取成功", pageBean);
    }

    /**
     * 退出
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/logout")
    public ResultData<String> logout(HttpServletRequest request, HttpServletResponse response) {
        EbSystemUser systemUser =null;
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            CusterUserDetails user = (CusterUserDetails) authentication.getPrincipal();
            systemUser = user.getUser();
            new SecurityContextLogoutHandler().logout(request, response, authentication);
            redisUtils.delete(systemUser.getUsername() + "Authorization");
        }
        return ResultData.success("退出成功");
    }

    /**
     * 获取基础统计
     * @return
     */
    @GetMapping("/statistics")
    public ResultData<Map> statistics() {
        GetCunrrentUser getCunrrentUser = new GetCunrrentUser();
        EbSystemUser systemUser=getCunrrentUser.getUser();
        LambdaQueryWrapper<EbSystemUser> queryWrapper= new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(EbSystemUser::getUpdateTime);
        int count = (int) service.count(queryWrapper);

        LambdaQueryWrapper<EbSystemUploadfile> uploadWrapper= new LambdaQueryWrapper<>();
        uploadWrapper.orderByAsc(EbSystemUploadfile::getUpdateTime);
        int countup = (int) uploadfileService.count(uploadWrapper);

        LambdaQueryWrapper<EbSystemLoginLog> loginLogWrapper= new LambdaQueryWrapper<>();
        loginLogWrapper.eq(EbSystemLoginLog::getUsername,systemUser.getUsername());
        int countloginlog = (int) loginLogService.count(loginLogWrapper);

        LambdaQueryWrapper<EbSystemOperLog> operlogWrapper= new LambdaQueryWrapper<>();
        operlogWrapper.eq(EbSystemOperLog::getUsername,systemUser.getUsername());
        int countoperlog = (int) operLogService.count(operlogWrapper);

        Map<String,Object> map =  new HashMap<>();
        map.put("user",count);
        map.put("attach",countup);
        map.put("login",countloginlog);
        map.put("operate",countoperlog);
        return ResultData.success("获取成功", map);
    }

}
